package rest;

import com.thoughtworks.xstream.XStream;
import entities.Channel;
import entities.News;
import services.ChannelService;
import services.NewsService;
import services.ServiceException;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ws.rs.*;
import java.util.List;

/**
 * Rest service for work with channels and news
 * User: kaiser
 * Date: 8/2/13
 * Time: 12:10 AM
 */
@Stateless
@Path(value = "/top")
@Produces(value = "text/xml")
public class TopService {

    @EJB
    ChannelService channelService;

    @EJB
    NewsService newsService;

    /**
     * Get registered channels list
     *
     * @return XML with channels list
     */
    @GET
    @Path(value = "/channels")
    public String getChannels() {
        List<Channel> channels = channelService.getAllChannels();
        return toXML(channels);
    }

    /**
     * Method for getting registered news<br/>
     * if channel id exist in query return channel news not all
     * * example:  /top/news - news from all channels
     * * example:  /top/news?channel=habra - news from habra channel
     *
     * @param channel
     * @return
     */
    @GET
    @Path(value = "/news")
    public String getNews(@QueryParam("channel") String channel) {
        try {
            if (channel == null) {
                return toXML(newsService.getTopNews());
            } else {
                return toXML(newsService.getChannelNews(channel));
            }
        } catch (ServiceException e) {
            return getErrorResponse(e.getMessage());
        }
    }

    /**
     * Method for increase news rate<br/>
     * example:  /top/news/1?up
     *
     * @param newsId
     * @param up
     * @return
     */
    @PUT
    @Path(value = "/news/{newsId}")
    public String upNewsRank(@PathParam(value = "newsId") int newsId, @QueryParam("up") String up) {
        try {
            if (up != null) {
                newsService.upNewsRank(newsId);
            }
        } catch (ServiceException e) {
            return getErrorResponse(e.getMessage());
        }
        return "";
    }

    /**
     * Convert date to xml
     *
     * @param o object, collection, ... to convert
     * @return xml string
     */
    private String toXML(Object o) {
        XStream xstream = getXStream();
        return xstream.toXML(o);
    }

    /**
     * getting XStream object in prepared state
     *
     * @return XStream object
     */
    private XStream getXStream() {
        XStream xstream = new XStream();
        xstream.processAnnotations(Channel.class);
        xstream.processAnnotations(News.class);
        return xstream;
    }

    /**
     * Method for building XML string with error status and error message
     *
     * @param msg error message
     * @return XML with error date
     */
    private String getErrorResponse(String msg) {
        Response r = new Response();
        r.setStatus(Response.STATUS_ERROR);
        r.setMessage(msg);
        return toXML(r);
    }
}
